﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tasker.Composition.Events;

namespace Tasker.Composition
{
    public static class Resolver
    {
        #region Fields
        static List<IDependencyResolver> _resolvers;
        static IContextContainer _contextContainer;
        #endregion

        #region Ctor
        static Resolver()
        {
            _resolvers = new List<IDependencyResolver>();
        }
        #endregion

        #region Public methods
        public static void AddResolver(IDependencyResolver resolver)
        {
            _resolvers.Add(resolver);
        }

        public static void Initialize(IContextContainer contextContainer)
        {
            _contextContainer = contextContainer;
            AddResolver(new CompositionResolver());
            Resolve<IEventAggregator>().RegisterEventHandlers();
        }

        public static void DisposeCurrentContext()
        {
            if (_contextContainer != null)
                foreach (var instance in _contextContainer.GetInstances().OfType<IDisposable>())
                    instance.Dispose();
        }

        public static object Resolve(Type type)
        {
            var resolvedInstance = _contextContainer.GetInstance(type);
            if (resolvedInstance == null)
            {
                resolvedInstance = Activator.CreateInstance(type);
                _contextContainer.RegisterInstance(type, resolvedInstance);
            }
            return resolvedInstance;
        }

        public static T Resolve<T>()
        {
            T resolvedInstance = (T)_contextContainer.GetInstance(typeof(T));

            if (resolvedInstance == null)
                foreach (var typeResolver in _resolvers.OfType<IDependencyTypeResolver<T>>())
                {
                    resolvedInstance = typeResolver.Resolve();
                    if (resolvedInstance != null)
                    {
                        _contextContainer.RegisterInstance(typeof(T), resolvedInstance);
                        return resolvedInstance;
                    }
                }
            return resolvedInstance;
        }
        #endregion
    }
}
